home *** CD-ROM | disk | FTP | other *** search
- Program Tic_Tac_Toe;
-
- Uses Dos,Graph,Crt;
-
- {Beta version of TicTacToe Game by Robert H Snow
- Used as a starting point for Reasearch Into
- Artifical Intelligence by SCT. It Is Very
- Crude and uses a very simple way of trying to win
- It Store all moves in a winning game and how many
- times it has won then on a given move tries
- several different possible moves and picks the
- one that has won the most games. after several
- thousand Games It is intersting to look at the
- Ticmem file.
- This Program works without ever knowing any of
- the rules of how to win ie, No hardwired responses.
- It also plays only player2. If you want to make
- your own tictactoe game several of the routines
- will be useful to you like Open, RandMove, and
- Winner. Note: try changing the winning combonations
- in Winner and this will still learn what wins, ie: Four Corners}
-
- {Tic Tac Toe by Robert Snow, CIS 76136,1553}
-
-
-
- Const
- Games = 1024; {How Many Games to play this session}
- TotalGameMemory = 256; {How Much Memory do I use 128-256 seem to be best}
- FileName = 'c:\pascal\prog\ticmem.'; {FileName for Memory File}
- GStep = (Games div 200) + 1;
- BarStep = Games div 16;
- XOffset = 30; {Where to put the board on the Screen X-Axis}
- YOffset = 40; {Where to put board on Screen Y-Axis}
- SortStep = 128; {How often to sort memory}
- PurgeBefore = 1024; {Keep only games that have won in the last # of games}
- MaxX = 320; {Currently Set for CGA}
- MaxY = 200; {Currently Set for CGA}
-
- Type
- Board = Array[1..3, 1..3] of 0..2;
- GameMem = Array[1..TotalGameMemory] of Board;
-
- Var
- GameMemory, CurrentGameMemory: GameMem;
- CurrentBoard,Test,LastBoard: Board;
- FileString: String;
- Wins: Array[1..TotalGameMemory] of Integer;
- LastWin: Array[1..TotalGameMemory] of Word;
- Turn,Player,CTest,
- GameCount,tr1,tr2,
- Winner1,Winner2,
- MostWins,MoveNum,
- Num,TimesWon,Hr,Min,EHr,Emin,sec,sec100:Word;
- Checker: Byte;
- InMem: Boolean;
- TotalGames,Count: Word;
- Ph,Pm: Integer;
-
-
- Procedure DrawField;
- Var GD,GM: Integer;
- Begin
- GD:=Detect;
- InitGraph(GD,GM,'');
- SetFillStyle(SolidFill,Blue);
- SetColor(Black);
- Bar3D(105+XOffSet,5+YOffSet,111+XOffSet,150+YOffSet,0,TopOff);
- Bar3D(160+XOffSet,5+YOffSet,166+XOffSet,150+YOffSet,0,TopOff);
- Bar3d(055+XOffSet,50+YOffSet,215+XOffSet,56+YOffSet,0,TopOff);
- Bar3d(055+XOffSet,100+YOffSet,215+XOffSet,106+YOffSet,0,TopOff);
- SetTextStyle(TriplexFont,1,4);
- SetTextJustify(CenterText,CenterText);
- SetColor(Magenta);
- OutTextXY(MaxX-30,MaxY-125,'The Student 1.0');
- SetColor(Red);
- Rectangle(1,MaxY-1,10,MaxY-(Games div GStep));
- SetColor(Red);
- Rectangle(0,MaxY,11,(MaxY-3)-(Games div GStep)+1);
- SetTextStyle(SmallFont,0,4);
- SetColor(Yellow);
- OutTextXY(27,MaxY-7,'Start');
- OutTextXY(30,(MaxY+3)-(Games div GStep),'Finish');
- SetTextStyle(TriplexFont,0,6);
- End;
-
-
- Procedure Init;
- var x,y: Word;
- begin
- for x:=1 to 3 do
- for y:=1 to 3 do
- CurrentBoard[x,y]:=0;
- end;
-
- Procedure FileIt(GMem: GameMem);
- Var
- Count,x,y: Word;
- f: Text;
- Begin
- Assign(f, FileString);
- Rewrite(f);
- For Count:=1 to TotalGameMemory Do Begin
- For x:=1 to 3 do Begin
- For y:=1 to 3 do
- Write(f, (GMem[Count,x,y]):4);
- Writeln(f);
- End;
- Writeln(f, Wins[Count]);
- Writeln(f, LastWin[Count]);
- Writeln(f);
- End;
- Writeln(f, Winner1);
- Writeln(f, Winner2);
- Writeln(f, (TotalGames + GameCount));
- Close(f)
- End;
-
- Procedure ReadMemory(Var GMem: GameMem);
- Var
- Count,x,y: Word;
- Sv: String[4];
- SvBig: String[6];
- f: Text;
- c: Integer;
-
- Begin
- Assign(f, FileString);
- Reset(f);
- For Count:=1 to TotalGameMemory Do Begin
- For x:=1 to 3 Do Begin
- For y:=1 to 3 Do Begin
- Read(f, Sv);
- Val(Sv, GMem[Count,x,y],c)
- End;
- Readln(f);
- End;
- Readln(f, SvBig);
- Val(SvBig, Wins[Count],c);
- Readln(f, SvBig);
- Val(SvBig, LastWin[Count],c);
- Readln(f)
- End;
- Readln(f, SvBig);
- Val(SvBig, Winner1, c);
- Readln(f, SvBig);
- Val(SvBig, Winner2, c);
- Readln(f, SvBig);
- Val(SvBig, TotalGames, c);
- Close(f)
- End;
-
-
-
- Function Open(var game: board): Boolean;
- var
- x,y: Word;
- begin
- Open:= false;
- for x:=1 to 3 do
- for y:=1 to 3 do
- if game[x,y]=0 then Open:= true
- end;
-
- Procedure RandMove(player: Word; Var CBoard: Board);
- var
- x,y: Word;
- begin
- repeat
- x:= random(3)+1;
- y:= random(3)+1;
- until CBoard[x, y] = 0;
- CBoard[x,y]:= Player
- end;
-
- Procedure ClearMem(CMem: GameMem);
- var i,x,y:Word;
- begin
- for i:=1 to TotalGameMemory do
- begin
- for x:=1 to 3 do
- for y:=1 to 3 do
- CMem[i,x,y]:=0;
- end
- end;
-
-
- Function Winner(CGame: Board): Integer;
- var
- x,y,Player: Word;
- begin
- Winner:=0;
- for player:=1 to 2 do
- begin
- for x:=1 to 3 do
- if (CGame[x,1]=player) and (CGame[x,2]=player) and (CGame[x,3]=player) then
- Winner:= player;
- for y:=1 to 3 do
- if (CGame[1,y]=player) and (CGame[2,y]=player) and (CGame[3,y]=player) then
- Winner:= player;
- if (CGame[1,1]=player) and (CGame[2,2]=player) and (CGame[3,3]=player) then
- Winner:= player;
- if (CGame[3,1]=player) and (CGame[2,2]=player) and (CGame[1,3]=player) then
- Winner:= player
- end
- end;
-
- Procedure DrawBoard(CB,OB: Board);
- Var X,Y: Byte;
- Begin
- SetColor(Black);
- For X:=1 to 3 do
- For Y:=1 to 3 do Begin
- Case OB[x,y] of
- 1: OutTextXY(((x*55)+25+XOffSet),((y*50)+(YOffSet-27)), 'O');
- 2: OutTextXY(((x*55)+25+XOffSet),((y*50)+(YOffSet-27)),'X')
- End
- End;
- SetColor(Yellow);
- For X:=1 to 3 do
- For Y:=1 to 3 do Begin
- Case CB[x,y] of
- 1: OutTextXY(((x*55)+25+XOffSet),((y*50)+(YOffSet-27)),'O');
- 2: OutTextXY(((x*55)+25+XOffSet),((y*50)+(YOffSet-27)),'X')
- End
- End
- End;
-
-
- Procedure Store(Game: Board; Turn: Integer);
- begin
- CurrentGameMemory[turn]:=Game;
- end;
-
- Procedure SortMem(Var GMem: GameMem);
- Var Changed: Boolean;
- Count: Integer;
- Temp: Board;
- WinsTemp: Integer;
-
- Begin
- Repeat
- Changed:=False;
- For Count:=1 to TotalGameMemory-1 Do
- If (Wins[Count+1]>Wins[Count]) then Begin
- Temp:=GMem[Count+1];
- GMem[Count+1]:=GMem[Count];
- GMem[Count]:=Temp;
- WinsTemp:=Wins[Count+1];
- Wins[Count+1]:=Wins[Count];
- Wins[Count]:=WinsTemp;
- Changed:=True
- End;
- Until (Not Changed)
- End;
-
-
-
-
- Procedure Memry(Last: GameMem; turns: Integer; Val: Integer);
- var
- gturn,Count,x,y: Word;
- found: Boolean;
-
- Function Match(GameMemory, Last: GameMem): Boolean;
- var TempX,TempY,x,y: Word;
- Match1, Match2, Match3, Match4: Boolean;
- begin
- Match:=True;
- Match1:=True;
- Match2:=True;
- Match3:=True;
- Match4:=True;
- For x:=1 to 3 do
- For y:=1 to 3 do Begin
- TempX:=x;TempY:=y;
- if Last[gturn,x,y] <> GameMemory[Count,TempX,TempY] then Match1:=False;
- IF x=1 then TempX:=3;
- IF x=3 then TempX:=1;
- IF Last[gturn,x,y] <> GameMemory[Count,TempX,TempY] then Match2:=False;
- IF y=1 then TempY:=3;
- IF y=3 then TempY:=1;
- IF Last[gturn,x,y] <> GameMemory[Count,TempX,TempY] then Match3:=False;
- TempX:=x;
- IF Last[gturn,x,y] <> GameMemory[Count,TempX,TempY] then Match4:=False;
- End;
- If (Not Match1) and (Not Match2) and (Not Match3) and (Not Match4) then
- Match:=False
- end;
-
- begin
- for gturn:=1 to turns do
- begin
- found:= false;
- Count:=1;
- Repeat
- IF match(GameMemory, Last) then
- begin
- Wins[Count]:=Wins[Count]+Val;
- If Val=1 Then LastWin[Count]:=GameCount + TotalGames;
- found:= true
- end;
- Count:=Count+1
- Until ((Count-1)=TotalGameMemory) or Found;
- If ((not found) and (val=1)) then
- Begin
- Found:=false;
- Count:=1;
- Repeat
- If (Wins[Count]<1) then
- Begin
- Found:=True;
- GameMemory[Count]:=Last[gturn];
- Wins[Count]:=1;
- LastWin[Count]:= GameCount + TotalGames;
- end;
- Count:=Count+1;
- Until ((Count-1)=TotalGameMemory) or Found
- end
- end;
- end;
-
- Procedure Purge(GMem: GameMem);
- var count: Word;
- Begin
- For Count:=1 to TotalGameMemory Do
- If LastWin[Count]<((TotalGames+GameCount)-(PurgeBefore)) Then
- Wins[Count]:=0;
- End;
-
- Procedure DumpMem(GameMemory: GameMem);
- var Count,x,y: Word;
- begin
- FOR Count:=TotalGameMemory Downto 1 do
- BEGIN
- For x:=1 To 3 Do
- Begin
- For y:=1 To 3 Do
- write(GameMemory[Count,x,y],' ');
- writeln
- End;
- writeln('Wins..', Wins[Count]);
- writeln
- End
- End;
-
-
-
- Procedure InMemory(CGame: Board; Var Num, TimesWon: Word);
- var TempX,TempY,x,y,Count: Word;
- Match1, Match2, Match3, Match4: Boolean;
- Begin
- TimesWon:=0;
- Count:=1;
- Repeat
- Match1:=True;
- Match2:=True;
- Match3:=True;
- Match4:=True;
- For x:=1 to 3 do
- For y:=1 to 3 do Begin
- TempX:=x;TempY:=y;
- if CGame[x,y] <> GameMemory[Count,TempX,TempY] then Match1:=False;
- IF x=1 then TempX:=3;
- IF x=3 then TempX:=1;
- IF CGame[x,y] <> GameMemory[Count,TempX,TempY] then Match2:=False;
- IF y=1 then TempY:=3;
- IF y=3 then TempY:=1;
- IF CGame[x,y] <> GameMemory[Count,TempX,TempY] then Match3:=False;
- TempX:=x;
- IF CGame[x,y] <> GameMemory[Count,TempX,TempY] then Match4:=False;
- End;
- If (Match1) or (Match2) or (Match3) or (Match4) Then Begin
- TimesWon:=Wins[Count];
- Num:=Count
- End;
- Count:=Count+1;
- Until ((Count-1)=Num) or (TimesWon <> 0)
- End;
-
- Function FileExists(FileName: String): Boolean;
- var f: text;
- Begin
- {$I-}
- Assign(f,FileName);
- Reset(f);
- Close(f);
- {I+}
- FileExists := (IOResult = 0) and (FileName <> '');
- end;
-
-
-
-
- BEGIN
- Str(TotalGameMemory, FileString);
- FileString:= FileName + FileString;
- GetTime(Hr,Min,sec,sec100);
- Writeln(Hr,':',Min);
- Randomize;
- If (Not FileExists(FileString)) then
- Begin
- For Count:=1 to TotalGameMemory Do Begin
- LastWin[Count]:=0;
- Wins[Count]:=0
- End;
- TotalGames:=0;
- Winner1:=0;
- Winner2:=0;
- ClearMem(GameMemory);
- FileIt(GameMemory)
- End;
- ReadMemory(GameMemory);
- DrawField;
- SetFillStyle(LineFill,Red);
- GameCount:=0;
- Repeat
- GameCount:=GameCount+1;
- If (GameCount/GStep) = (GameCount div GStep) then Bar(2,200,9,200-(GameCount div GStep));
- If (GameCount/SortStep) = (GameCount div SortStep) then
- Begin
- SortMem(GameMemory);
- Purge(GameMemory)
- End;
- ClearMem(CurrentGameMemory);
- Init;
- Turn:=0;
- Repeat
- Turn:=Turn+1;
- Player:=1;
- RandMove(Player ,CurrentBoard);
- Player:=2;
- InMem:=False;
- If (Winner(CurrentBoard)<>1) and (Open(CurrentBoard)) Then
- Begin
- Num:=128;
- MostWins:=1;
- MoveNum:=0;
- For CTest:=1 To (12-(2*turn)) Do Begin
- Test:=CurrentBoard;
- RandMove(Player,Test);
- InMemory(Test,Num,TimesWon);
- If TimesWon > MostWins then Begin
- MoveNum:=Num;
- MostWins:=TimesWon;
- InMem:=True
- End
- End;
- Case InMem of
- False: RandMove(Player,CurrentBoard);
- True: Begin
- CurrentBoard:=GameMemory[MoveNum]
- End
- End;
- End;
- Store(CurrentBoard, Turn);
- DrawBoard(CurrentBoard, LastBoard);
- LastBoard:=CurrentBoard;
- Checker:=Winner(CurrentBoard)
- Until (Checker<>0) or (Not Open(CurrentBoard));
- Case Checker of
- 1: Begin
- Memry(CurrentGameMemory, Turn, -1);
- Winner1:=Winner1+1
- End;
- 2: Begin
- Memry(CurrentGameMemory, Turn, 1);
- Winner2:=Winner2+1
- End
- End
- Until (GameCount=Games) or (KeyPressed);
- GetTime(EHr,EMin,sec,sec100);
- CloseGraph;
- If Ehr<hr then Ehr:=Ehr+24;
- ph:=Ehr-hr;
- pm:=emin-min;
- pm:=(ph*60)+pm;
- Writeln('I Played ',GameCount,' Games In ',pm,' Minutes.');
- If Pm <> 0 Then Writeln('I Averaged ',GameCount div pm,' Games a minute.');
- SortMem(GameMemory);
- Purge(GameMemory);
- Writeln('My Opponent Has Won ',Winner1,' Games.');
- Writeln('I Have Won ',Winner2,' Games.');
- Writeln('I Have Played a Total of ', TotalGames + GameCount,' Games.');
- Writeln('I Have Won ',trunc((Winner2)/(TotalGames + GameCount)*100),'% of the Games.');
- Writeln('My Opponent Has won ',trunc((Winner1)/(totalGames + GameCount)*100),'% of the Games.');
- FileIt(GameMemory);
- Readln
- END.